Completed
Push — master ( 1b8bc3...b57db7 )
by Ralf
18:51
created

fw_browser.js ➔ ???   B

Complexity

Conditions 1
Paths 3072

Size

Total Lines 349

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
nc 3072
nop 0
dl 0
loc 349
rs 8.2857
c 1
b 0
f 0

9 Functions

Rating   Name   Duplication   Size   Complexity  
A fw_browser.js ➔ ... ➔ Class.extend.init 0 12 1
B fw_browser.js ➔ ... ➔ Class.extend.setBrowserType 0 41 6
A fw_browser.js ➔ ... ➔ Class.extend.callResizeHandler 0 14 4
A fw_browser.js ➔ ... ➔ Class.extend.resize 0 14 3
B fw_browser.js ➔ ... ➔ Class.extend.browse_finished 0 29 4
A fw_browser.js ➔ ... ➔ Class.extend.browse_callback 0 8 3
A fw_browser.js ➔ ... ➔ Class.extend.reload 0 14 3
A fw_browser.js ➔ ... ➔ Class.extend.blank 0 4 1
F fw_browser.js ➔ ... ➔ Class.extend.browse 0 167 21

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
/**
2
 * eGroupware Framework browser object
3
 * @package framework
4
 * @author Hadi Nategh <[email protected]>
5
 * @copyright Stylite AG 2014
6
 * @description Framework browser object, is implementation of browser class in order to display application content
7
 */
8
9
/*egw:uses
10
	jquery.jquery;
11
	egw_action.egw_action_common;
12
	egw_inheritance.js;
13
*/
14
15
/**
16
 * Constants definition
17
 */
18
EGW_BROWSER_TYPE_NONE = 0;
19
EGW_BROWSER_TYPE_IFRAME = 1;
20
EGW_BROWSER_TYPE_DIV = 2;
21
22
var fw_browser = (function(){ "use strict"; return Class.extend(
23
{
24
	/**
25
	 * @param {string} _app
26
	 * @param {function} _heightCallback
27
	 * Framework browser class constructor
28
	 */
29
	init: function (_app, _heightCallback){
30
		//Create a div which contains both, the legacy iframe and the contentDiv
31
		this.baseDiv = document.createElement('div');
32
		this.type = EGW_BROWSER_TYPE_NONE;
33
		this.iframe = null;
34
		this.contentDiv = null;
35
		this.heightCallback = _heightCallback;
36
		this.app = _app;
37
		this.currentLocation = '';
38
		this.ajaxLoaderDiv = null;
39
		this.loadingDeferred = null;
40
	},
41
42
	/**
43
	 * Triggers resize event on window
44
	 */
45
	callResizeHandler: function()
46
	{
47
		var wnd = window;
48
		if (this.iframe)
49
		{
50
			wnd = this.iframe.contentWindow;
51
		}
52
53
		// Call the resize handler (we have to use the jquery object of the iframe!)
54
		if (wnd && typeof wnd.$j != "undefined")
55
		{
56
			wnd.$j(wnd).trigger("resize");
57
		}
58
	},
59
60
	/**
61
	* Resizes both, the contentDiv and the iframe to the size returned from the heightCallback
62
	*/
63
	resize: function()
64
	{
65
		var height = this.heightCallback.call(this.iframe) + 'px';
66
67
		//Set the height of the content div or the iframe
68
		if (this.contentDiv)
69
		{
70
			this.contentDiv.style.height = height;
71
		}
72
		if (this.iframe)
73
		{
74
			this.iframe.style.height = height;
75
		}
76
	},
77
78
	/**
79
	 * Sets browser type either DIV or IFRAME
80
	 *
81
	 * @param {int} _type
82
	 */
83
	setBrowserType: function(_type)
84
	{
85
		//Only do anything if the browser type has changed
86
		if (_type != this.type)
87
		{
88
			//Destroy the iframe and/or the contentDiv
89
			$j(this.baseDiv).empty();
90
			this.iframe = null;
91
			this.contentDiv = null;
92
			if(this.loadingDeferred && this.type)
93
			{
94
				this.loadingDeferred.reject();
95
			}
96
97
			switch (_type)
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
98
			{
99
				//Create the div for displaying the content
100
				case EGW_BROWSER_TYPE_DIV:
101
					this.contentDiv = document.createElement('div');
102
					$j(this.contentDiv).addClass('egw_fw_content_browser_div');
103
					$j(this.baseDiv).append(this.contentDiv);
104
105
					break;
106
107
				case EGW_BROWSER_TYPE_IFRAME:
108
					//Create the iframe
109
					this.iframe = document.createElement('iframe');
110
					this.iframe.style.width = "100%";
111
					this.iframe.style.borderWidth = 0;
112
					this.iframe.frameBorder = 0;
113
					this.iframe.name = 'egw_app_iframe_' + this.app.appName;
114
					$j(this.iframe).addClass('egw_fw_content_browser_iframe');
115
					$j(this.baseDiv).append(this.iframe);
116
117
					break;
118
			}
119
120
			this.resize();
121
			this.type = _type;
122
		}
123
	},
124
125
	/**
126
	 * Sets url to browse and load the content in proper content browser
127
	 * @param {string} _url
128
	 * @return {Deferred} Returns a Deferred promise object
129
	 */
130
	browse: function(_url)
131
	{
132
		// check if app has its own linkHandler and it accepts the link (returns true), or returns different url instead
133
		if (typeof app == 'object' && typeof app[this.app.appName] == 'object' &&
134
				typeof app[this.app.appName].linkHandler == 'function')
135
		{
136
			var ret = app[this.app.appName].linkHandler.call(app[this.app.appName], _url);
137
			{
138
				if (ret === true) return this.loadingDeferred.promise();
139
				if (typeof ret === 'string')
140
				{
141
					_url = ret;
142
				}
143
			}
144
		}
145
		var useIframe = true;
146
		var targetUrl = _url;
147
		if(_url == this.currentLocation && this.loadingDeferred != null)
148
		{
149
			// Still loading
150
			return this.loadingDeferred.promise();
151
		}
152
153
		// Show loader div, start blocking
154
		var self = this;
155
		this.ajaxLoaderDiv = egw.loading_prompt(this.app.appName,true,egw.lang('please wait...'),this.baseDiv, egwIsMobile()?'horizental':'spinner');
156
		this.loadingDeferred = new jQuery.Deferred();
157
158
		// Try to escape from infinitive not resolved loadingDeferred
159
		// At least user can close the broken tab and work with the others.
160
		// Define a escape timeout for 5 sec
161
		this.ajaxLoaderDivTimeout = setTimeout(function(){
162
			(self.ajaxLoaderDiv || jQuery('div.loading')).hide().remove();
163
			self.ajaxLoaderDiv = egw.loading_prompt(self.app.appName,false);
164
		},5000);
165
166
		this.loadingDeferred.always(function() {
167
			if(self.ajaxLoaderDiv)
168
			{
169
170
				self.ajaxLoaderDiv = egw.loading_prompt(self.app.appName,false);
171
				// Remove escape timeout
172
				clearTimeout(self.ajaxLoaderDivTimeout);
173
			}
174
175
176
		});
177
178
		// Check whether the given url is a pseudo url which should be executed
179
		// by calling the ajax_exec function
180
		// we now send whole url back to server, so apps can use $_GET['ajax']==='true'
181
		// to detect app-icon was clicked and eg. further reset filters
182
		var matches = _url.match(/\/index.php\?menuaction=([A-Za-z0-9_\.]*.*&ajax=true.*)$/);
183
		if (matches) {
184
			// Matches[1] contains the menuaction which should be executed - replace
185
			// the given url with the following line. This will be evaluated by the
186
			// jdots_framework ajax_exec function which will be called by the code
187
			// below as we set useIframe to false.
188
			targetUrl = "index.php?menuaction=" + matches[1];
189
			useIframe = false;
190
		}
191
192
		// Destroy application js
193
		if(app[this.app.appName] && app[this.app.appName].destroy)
194
		{
195
			app[this.app.appName].destroy();
196
		}
197
198
		// Unload etemplate2, if there
199
		if(typeof etemplate2 == "function")
200
		{
201
			// Clear all etemplates on this tab, regardless of application, by using DOM nodes
202
			$j('.et2_container',this.contentDiv||this.baseDiv).each(function() {
203
				var et = etemplate2.getById(this.id);
204
				if(et !== null)
205
				{
206
					et.clear();
207
				}
208
			});
209
		}
210
		else if(this.iframe && typeof this.iframe.contentWindow.etemplate2 == "function")
211
		{
212
			try
213
			{
214
				if(typeof this.iframe.contentWindow.etemplate2 == "function")
215
				{
216
					// Clear all etemplates on this tab, regardless of application, by using DOM nodes
217
					var content = this.iframe.contentWindow;
218
					$j('.et2_container',this.iframe.contentWindow).each(function() {
219
						var et = content.etemplate2.getById(this.id);
220
						if(et !== null)
221
						{
222
							et.clear();
223
						}
224
					});
225
				}
226
			}
227
			catch(e) {}	// catch error if eg. SiteMgr runs a different origin, otherwise tab cant be closed
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
228
		}
229
230
		// Save the actual url which has been passed as parameter
231
		this.currentLocation = _url;
232
233
		//Set the browser type
234
		if (useIframe)
235
		{
236
			this.setBrowserType(EGW_BROWSER_TYPE_IFRAME);
237
238
			//Postpone the actual "navigation" - gives some speedup with internet explorer
239
			//as it does no longer blocks the complete page until all frames have loaded.
240
			window.setTimeout(function() {
241
				//Load the iframe content
242
				self.iframe.src = _url;
243
244
				//Set the "_legacy_iframe" flag to allow link handlers to easily determine
245
				//the type of the link source
246
				if (self.iframe && self.iframe.contentWindow) {
247
					try {
248
						self.iframe.contentWindow._legacy_iframe = true;
249
250
						// Focus the iframe of the current application
251
						if (self.app == framework.activeApp)
252
						{
253
							self.iframe.contentWindow.focus();
254
						}
255
					}
256
					catch (e) {
257
						// ignoer SecurityError: Blocked a frame ..., caused by different origin
258
					}
259
				}
260
261
				if(self.loadingDeferred)
262
				{
263
					self.loadingDeferred.resolve();
264
					self.loadingDeferred = null;
265
				}
266
			}, 1);
267
		}
268
		else
269
		{
270
			this.setBrowserType(EGW_BROWSER_TYPE_DIV);
271
272
			//Special treatement of "about:blank"
273
			if (targetUrl == "about:blank")
274
			{
275
				if (this.app.sidemenuEntry)
276
					this.app.sidemenuEntry.hideAjaxLoader();
277
278
				egw_widgetReplace(this.app.appName, this.contentDiv, '');
279
			}
280
			else
281
			{
282
				//Perform an AJAX request loading application output
283
				if (this.app.sidemenuEntry)
284
					this.app.sidemenuEntry.showAjaxLoader();
285
				this.data = "";
286
				$j(this.contentDiv).empty();
287
				var self_egw = egw(this.app.appName);
288
				var req = self_egw.json(
289
					this.app.getMenuaction('ajax_exec'),
290
					[targetUrl], this.browse_callback,this, true, this
291
				);
292
				req.sendRequest();
293
			}
294
		}
295
		return this.loadingDeferred.promise();
296
	},
297
298
	/**
299
	 *
300
	 * @param {type} _data
301
	 * @return {undefined} return undefined if data is not from the right response
302
	 */
303
	browse_callback: function(_data)
304
	{
305
		// Abort if data is from wrong kind of response - only 'data'
306
		if(!_data || _data.type != undefined) return;
307
308
		this.data = _data[0];
309
		this.browse_finished();
310
	},
311
312
	/**
313
	 *  Get call via browse_callback in order to attaching nodes to the DOM
314
	 */
315
	browse_finished: function()
316
	{
317
		if (this.app.sidemenuEntry)
318
			this.app.sidemenuEntry.hideAjaxLoader();
319
	//	egw_widgetReplace(this.app.appName, this.contentDiv, this.data);
320
		var content = {
321
			html: this.data,
322
			js: ''
323
		};
324
325
		if (this.app == framework.activeApp)
326
		{
327
			window.focus();
328
		}
329
330
		egw_seperateJavaScript(content);
331
332
		// Insert the content
333
		$j(this.contentDiv).append(content.html);
334
335
		// Run the javascript code
336
		//console.log(content.js);
337
		$j(this.contentDiv).append(content.js);
338
339
		if(this.loadingDeferred)
340
		{
341
			this.loadingDeferred.resolve();
342
		}
343
	},
344
345
	/**
346
	 * REload the content of the browser object
347
	 */
348
	reload: function()
349
	{
350
		switch (this.type)
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
351
		{
352
			case EGW_BROWSER_TYPE_DIV:
353
				this.browse(this.currentLocation);
354
				break;
355
356
			case EGW_BROWSER_TYPE_IFRAME:
357
				//Do a simple reload in the iframe case
358
				this.iframe.contentWindow.location.reload();
359
				break;
360
		}
361
	},
362
363
	/**
364
	 *
365
	 */
366
	blank: function()
367
	{
368
		this.browse('about:blank', this.type == EGW_BROWSER_TYPE_IFRAME);
369
	}
370
});}).call(this);
371